home *** CD-ROM | disk | FTP | other *** search
/ World of Education / World of Education.iso / world_x / xcoral16.zip / FILE_SEL.C < prev    next >
C/C++ Source or Header  |  1993-01-15  |  21KB  |  765 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <X11/Xlib.h>
  16. #include <stdio.h>
  17. #include <dirent.h>
  18. #include <sys/param.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <malloc.h>
  22. #include <string.h>
  23.  
  24. #include "text.h"
  25. #include "options.h"
  26. #include "flist.h"
  27.  
  28. extern Display *dpy;
  29. extern char  *getcwd();
  30.  
  31. #define FS_SHADOW     6
  32. #define FS_SPACE    5
  33. #define FS_BUFFER_SIZE    10000
  34.  
  35. typedef struct {
  36.     Window         frame, shadow, title, dir, main, ok, cancel;
  37.     unsigned long     fg, bg, ts, bs, text_fg, text_bg;
  38.     XFontStruct    *font;
  39.         GC        gc;
  40.         int         width, height, title_height, button_width, button_height;
  41.         Text        *text;
  42.         Buf        *buf;
  43.         SWin        *scroll;
  44.         int        select;
  45.         int        m_width, m_height;
  46.         char        *dirname;
  47. } Selector;
  48.  
  49. /*
  50.  * Public
  51.  */
  52. extern void InitFileSelector ();
  53. extern char *GetStringFromSelect ( /* parent, type */ );
  54.  
  55. /* 
  56.  * Private
  57.  */
  58. static Selector fs;
  59. static void ButtonFileSelect (), ExposeFileSelect (), SetParams (),
  60.     CleanButton (),    RefreshFileSelect (), RefreshDirWindow (),
  61.     SelectFileItem (), UpdateFileItem (),ConfigFileSelect (),
  62.     SortFiles (), UnmapFileSelect ();
  63. static int MyCompare ();
  64.  
  65.  
  66. /*
  67. **    Function name : InitFileSelector
  68. **
  69. **    Description : Creation des fenetres, boutons, scroll etc...
  70. **    Input : 
  71. **    Ouput :
  72. */
  73. void InitFileSelector ()
  74. {
  75.     XSetWindowAttributes att_f;    
  76.     Window     root;
  77.     int     screen;
  78.     unsigned long black, white;
  79.     XGCValues     gcv;
  80.  
  81.         screen = DefaultScreen ( dpy );
  82.     root = RootWindow ( dpy, screen );
  83.     black = BlackPixel ( dpy, DefaultScreen ( dpy ));
  84.     white = WhitePixel ( dpy, DefaultScreen ( dpy ));
  85.  
  86.     fs.fg = (DefaultDepth ( dpy, screen ) == 1) ? black : GetOpColor ( OP_MENU_FG );
  87.     fs.bg = (DefaultDepth ( dpy, screen ) == 1) ? white : GetOpColor ( OP_MENU_BG );
  88.     fs.text_bg = GetOpColor ( OP_TEXT_BG );
  89.     fs.text_fg = GetOpColor ( OP_TEXT_FG );
  90.     fs.ts = GetOpColor ( OP_MENU_TS );
  91.     fs.bs = GetOpColor ( OP_MENU_BS );
  92.     fs.font = GetOpFont ( OP_TEXT_FONT );
  93.  
  94.     fs.gc = XCreateGC ( dpy, DefaultRootWindow ( dpy ), 0,  &gcv );
  95.      XCopyGC ( dpy, DefaultGC (dpy, screen ), (~0), fs.gc );
  96.  
  97.     XSetFont ( dpy, fs.gc, fs.font -> fid );
  98.     XSetForeground ( dpy, fs.gc, fs.fg );
  99.     XSetBackground ( dpy, fs.gc, fs.bg );
  100.  
  101.     fs.title_height = fs.font -> ascent + fs.font-> descent + 8;
  102.     fs.button_height = fs.font -> ascent + fs.font-> descent + 8;
  103.     fs.width = DisplayWidth ( dpy,DefaultScreen ( dpy )) / 2;
  104.     fs.height = DisplayHeight ( dpy,DefaultScreen ( dpy ))/2;
  105.  
  106.         att_f.win_gravity = NorthWestGravity;
  107.     att_f.event_mask = 0;
  108.     att_f.override_redirect = False;
  109.     att_f.do_not_propagate_mask = NoEventMask;
  110.     att_f.cursor = None;
  111.     att_f.win_gravity = NorthWestGravity;
  112.  
  113.         fs.frame = XCreateWindow ( dpy, root, 0, 0, fs.width, fs.height, 0, 0,
  114.         InputOutput, CopyFromParent,
  115.         CWWinGravity | CWEventMask | CWOverrideRedirect |
  116.         CWDontPropagate | CWCursor, &att_f );
  117.  
  118.                 fs.shadow = XCreateSimpleWindow ( dpy, fs.frame, FS_SHADOW, FS_SHADOW, 
  119.         fs.width, fs.height, 0, black, black);
  120.  
  121.         fs.title = XCreateSimpleWindow (dpy, fs.frame, 
  122.         0, 0, fs.width, fs.title_height, 0 , black, fs.bg );
  123.  
  124.             fs.dir = XCreateSimpleWindow (dpy, fs.frame, 
  125.         0, fs.title_height, fs.width, fs.title_height, 0 , black, fs.bg );
  126.  
  127.         fs.main = XCreateSimpleWindow (dpy, fs.frame, 
  128.         0, (2*(fs.title_height)),
  129.                 fs.width, fs.height - fs.title_height, 0, black, fs.bg );
  130.            fs.button_width = XTextWidth ( fs.font, "  Ok...  ", 9 ) + 10;        
  131.     fs.ok = XCreateSimpleWindow (dpy, fs.main, 0, 0,
  132.         fs.button_width,fs.button_height, 0, black, fs.bg );
  133.     fs.cancel = XCreateSimpleWindow (dpy, fs.main, 0, 0,
  134.         fs.button_width, fs.button_height, 0, black, fs.bg );
  135.     
  136.     XSelectInput ( dpy, fs.title, ExposureMask );
  137.         XSelectInput ( dpy, fs.dir, ExposureMask );
  138.     XSelectInput ( dpy, fs.main, ExposureMask );
  139.     XSelectInput ( dpy, fs.ok, ExposureMask | ButtonPressMask | ButtonReleaseMask);
  140.     XSelectInput ( dpy, fs.cancel, ExposureMask | ButtonPressMask | ButtonReleaseMask);    
  141.  
  142.         fs.text = ( Text * ) MakeTextWindow ( dpy, fs.main, FS_SPACE, FS_SPACE );
  143.     fs.scroll = ( SWin  * ) MakeScroll ( dpy, fs.main,  0, FS_SPACE ); 
  144.     fs.text -> swin = fs.scroll;
  145.     fs.scroll -> text = (char *) fs.text;
  146.     fs.text -> mwin = 0;
  147.     fs.buf = (Buf *) GetBuffer ( (unsigned) FS_BUFFER_SIZE );
  148.     fs.text -> buf = fs.buf;
  149.     fs.select = 0;
  150.     fs.dirname = 0;
  151. }
  152.  
  153.  
  154. /*
  155. **    Function name : ReadDir
  156. **
  157. **    Description :  Charge les noms de fichiers dans le buffer.
  158. **    Input : Le nom de la directorie.
  159. **    Ouput : 0 si OK -1 sinon
  160. */
  161. static int ReadDir ( dir )
  162. char *dir;
  163. {
  164.     DIR *dirp;
  165.     struct dirent *dp;
  166.          register int n =0;
  167.         char **tmp;
  168.         register int i=0;
  169.         register int dir_len = 0;
  170.  
  171.     dirp = opendir( dir );
  172.         if ( dirp == 0 ) 
  173.         return -1;
  174.  
  175.     ClearBuffer ( fs.buf ); 
  176.     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) 
  177.             dir_len ++;
  178.         (void) closedir ( dirp );
  179.         dirp = opendir( dir );
  180.         tmp = (char **) malloc ( (unsigned) ( sizeof (char *) * (dir_len + 2)));
  181.  
  182.     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  183.         if ( (dp->d_name != 0) && (strlen(dp->d_name) != 0) ) {
  184.                         tmp [i] = (char *) malloc ( (unsigned) strlen (dp->d_name) + 2);
  185.             (void) strcpy ( (char *) tmp[i], dp->d_name );
  186.             i++;
  187.             }
  188.         }
  189.     qsort ( (char *) tmp, i, sizeof ( char *), MyCompare ); 
  190.     for ( n = 0; n < i; n++ ) {
  191.                 InsertNchar ( fs.buf, (char *) tmp [n], 
  192.                         strlen ((char *) tmp [n] ));
  193.               if ( tmp[n] != 0 )
  194.             (void) free ( (char *) tmp[n] );
  195.         InsertNchar ( fs.buf, "\n", 1 );
  196.         }
  197.        if ( tmp != 0 )
  198.         (void) free ( (char *) tmp );
  199.     SetParams ( FILESELECT, dir );
  200.         (void) closedir ( dirp );
  201.         return 0;
  202. }
  203.  
  204.  
  205. /*
  206. **    Function name : SetParams
  207. **
  208. **    Description : Positionne quelques parametres, en fonction
  209. **        du type d'objet a afficher.
  210. **    Input : Le type, la directorie.
  211. **    Ouput :
  212. */
  213. static void SetParams ( type, dir )
  214.     register int type;
  215.     register char *dir;
  216. {
  217.     register char *pathname;
  218.        register int n;
  219.  
  220.     fs.text -> modif = True;
  221.     (void) strcpy ( (char *) fs.text -> filename, "NoName" );
  222.     n = GetNumberOfLineInBuf ( fs.text -> buf );
  223.     fs.text -> lines_in_buf = n;
  224.     SetScrollLine ( fs.text -> swin, n );
  225.     HoleToLeft ( fs.buf );
  226.     
  227.     if ( fs.dirname != 0 )
  228.         (void) free ( fs.dirname );
  229.  
  230.     switch ( type ) {
  231.         case FILESELECT:
  232.                 pathname = (char *) malloc ( (unsigned) MAXPATHLEN + 2 );
  233.             (void) getcwd ( (char*) pathname, MAXPATHLEN + 2 );
  234.             if ( strcmp ( dir, "." ) == 0 ) {
  235.                     fs.dirname = ( char *) malloc ( (unsigned) strlen (pathname) +2 );
  236.                     (void) strcpy ( fs.dirname, (char *) pathname );
  237.             }
  238.             else {
  239.                     fs.dirname = ( char *) malloc ( (unsigned) strlen (dir) +2 );
  240.                     (void) strcpy ( fs.dirname, dir );
  241.             }
  242.                   if ( pathname != 0 )
  243.                     (void)  free ( pathname );
  244.             break;
  245.         case KILLBUF:
  246.             fs.dirname = ( char *) malloc ( (unsigned) 64 );
  247.                 (void) strcpy ( fs.dirname, "Select : " );
  248.             break;
  249.         case OPENFILES:
  250.             fs.dirname = ( char *) malloc ( (unsigned) 256 );
  251.                 (void) strcpy ( fs.dirname, "Select : " );
  252.             break;
  253.         default:
  254.             break;    
  255.     }
  256. }
  257.  
  258.  
  259. /*
  260. **    Function name : MyCompare
  261. **
  262. **    Description : Compare  2 chaines
  263. **    Input : 2 tableaux de chaines
  264. **    Ouput : Vrai si s1 = s2 Faux sinon
  265. */
  266. static int MyCompare ( s1, s2 )
  267.     register char **s1, **s2;
  268. {
  269.     return ( strcmp ( *s1, *s2 ));
  270. }
  271.  
  272.  
  273. /*
  274. **    Function name : GetStringFromSelect
  275. **
  276. **    Description : Retourne la chaine selectionnee.
  277. **    Input : La fenetre parent, le type d'objet
  278. **    Ouput : La chaine.
  279. */
  280. char *GetStringFromSelect ( window, type )
  281. Window window;
  282. register int type;
  283. {
  284.     register char *str, *tmp;
  285.     XEvent event;
  286.     int len;
  287.  
  288.     switch ( type ) {
  289.         case FILESELECT:
  290.                  (void) ReadDir ( "." );
  291.             break;
  292.         case KILLBUF:
  293.                   ClearBuffer ( fs.buf );         
  294.             (void) LoadKillBuffer ( fs.buf );
  295.             SetParams ( KILLBUF, (char *) 0 );
  296.             break;
  297.         case OPENFILES:
  298.             ClearBuffer ( fs.buf );
  299.             LoadFileNames ( fs.buf ); 
  300.             SetParams ( OPENFILES, (char *) 0 );
  301.             break;
  302.         default:
  303.         break;
  304.         
  305.     }
  306.     ConfigFileSelect ( window );
  307.  
  308.        XGrabPointer ( dpy, fs.frame, True, ButtonReleaseMask, GrabModeAsync,
  309.         GrabModeAsync, fs.frame, None, CurrentTime );
  310.  
  311.        for (;;) {
  312.         XNextEvent ( dpy, &event );
  313.         switch ( event.type ) {
  314.         case Expose:
  315.             ExposeFileSelect ( event.xexpose.window, type );
  316.             break;
  317.         case ButtonPress:
  318.             if ( event.xbutton.window == fs.cancel || event.xbutton.window == fs.ok ) {
  319.                 CleanButton ( event.xbutton.window, event.xbutton.button );
  320.                 if ( event.xbutton.window != fs.cancel ) {
  321.                     tmp = (char *) GetCurrentLine ( fs.buf, &len );
  322.                     tmp [len] = 0;
  323.                     switch ( type ) {
  324.                     case FILESELECT:
  325.                         str = (char *) malloc ( (unsigned) len + strlen(fs.dirname) + 2 );
  326.                         if ( strcmp ( tmp, "." ) == 0 || fs.select == 0 ) 
  327.                             (void) sprintf ( str, "%s", fs.dirname );
  328.                            else {
  329.                             if ( strcmp ( fs.dirname, "/" ) == 0 ) 
  330.                                 (void) sprintf ( str, "/%s", tmp );    
  331.                             else
  332.                                       (void) sprintf ( str, "%s/%s", fs.dirname, tmp );
  333.                         }
  334.                         break;
  335.                     case KILLBUF:
  336.                     case OPENFILES:
  337.                         str = (char *) malloc ( (unsigned) len + 2 );
  338.                         (void) sprintf ( str, "%s", tmp );
  339.                         break;
  340.                     default:
  341.                         break;
  342.                     }
  343.                     fs.select = 0;
  344.                     XUngrabPointer ( dpy, CurrentTime );
  345.                     UnmapFileSelect ();
  346.                     return ( str );
  347.                 }
  348.                 fs.select = 0;
  349.                 XUngrabPointer ( dpy, CurrentTime );
  350.                 UnmapFileSelect ();
  351.                 return 0;                
  352.             }
  353.             else
  354.                 ButtonFileSelect ( event.xbutton.window,
  355.                     event.xbutton.x, event.xbutton.y, type );
  356.             break;
  357.         default :
  358.             break;    
  359.         }
  360.     }
  361. }
  362.  
  363.  
  364. /*
  365. **    Function name : ButtonFileSelect
  366. **
  367. **    Description : Traitement de l'evennement 'ButtonPress'
  368. **    Input : La fenetre, la position, le type. 
  369. **    Ouput :
  370. */
  371. static void ButtonFileSelect ( w, x, y, type )
  372. Window w;
  373. register int x, y;
  374. register int type;
  375. {
  376.     int result;
  377.  
  378.     if ( ButtonPressInScroll ( fs.scroll,w, y, &result )) {
  379.         switch ( result ) {
  380.         case CURSOR:
  381.             UpdateFileItem ( fs.select );
  382.             /* Pour mettre a jour la ligne courante */
  383.             TextCursorOn ( fs.text );
  384.             TextCursorOff ( fs.text );
  385.             if ( (TextInBuf ( fs.text ) == True) 
  386.                 && ( fs.text -> lines_in_buf > 1 )) {
  387.                 HandleScrollBar ( dpy, fs.scroll, ScrollNLine );
  388.                 RefreshScrollBar ( dpy, fs.scroll );
  389.                 XGrabPointer ( dpy, fs.frame, True, ButtonReleaseMask, GrabModeAsync,
  390.                     GrabModeAsync, fs.frame, None, CurrentTime );
  391.             }
  392.             TextCursorOn ( fs.text );
  393.             TextCursorOff ( fs.text ); 
  394.             UpdateFileItem ( fs.select );
  395.             break;
  396.         case NEXT:
  397.             UpdateFileItem ( fs.select );
  398.             TextCursorOff ( fs.text );
  399.             NextPage ( fs.text  );
  400.             TextCursorOn ( fs.text ); 
  401.             TextCursorOff ( fs.text );
  402.             UpdateFileItem ( fs.select );
  403.             break;
  404.         case PREVIOUS:
  405.             UpdateFileItem ( fs.select );
  406.             TextCursorOff ( fs.text );
  407.             PreviousPage ( fs.text );
  408.             TextCursorOn ( fs.text );
  409.             TextCursorOff ( fs.text );
  410.             UpdateFileItem ( fs.select );
  411.             break;
  412.         }
  413.     }
  414.     else if ( w == fs.text -> window ) 
  415.         SelectFileItem ( x, y, type );
  416. }
  417.  
  418.  
  419. /*
  420. **    Function name : ExposeFileSelect
  421. **
  422. **    Description : Traitement de l'evennement 'Expose'
  423. **    Input : La fenetre, le type
  424. **    Ouput :
  425. */
  426. static void ExposeFileSelect ( w, type )
  427.     Window w;
  428.     register int type;
  429. {
  430.     register int x;
  431.     XEvent event;
  432.     char s_title [32];
  433.  
  434.     switch ( type ) {
  435.         case FILESELECT:
  436.             (void) strcpy ( s_title, "File Selection" );
  437.             break;
  438.         case KILLBUF:
  439.             (void) strcpy ( s_title, "Kill Buffers" );
  440.             break;
  441.         case OPENFILES:
  442.             (void) strcpy ( s_title, "Open Files" );
  443.             break;
  444.         default:
  445.             break;
  446.     }
  447.  
  448.     if ( w == fs.title ) {
  449.             x = XTextWidth ( fs.font, s_title, 14 );
  450.         XDrawString ( dpy, fs.title, fs.gc, (fs.m_width - x)/2,
  451.             fs.font -> ascent + 5, s_title, strlen (s_title) );
  452.         Display3D ( dpy, fs.title, fs.ts, fs.bs, 1, 0 );
  453.     }
  454.     if ( w == fs.dir ) {
  455.         FirstPage ( fs.text );
  456.         if ( type == FILESELECT ) 
  457.             RefreshDirWindow ( fs.dirname, FILESELECT  );
  458.         else
  459.             RefreshDirWindow ( fs.dirname, KILLBUF  );
  460.     }
  461.     else if ( w == fs.main ) 
  462.         Display3D ( dpy, fs.main, fs.ts, fs.bs, 1, 0 );
  463.     else if ( w == fs.ok ) {
  464.         switch ( type ) {
  465.             case FILESELECT:
  466.                 (void) strcpy ( s_title, "  Ok...  " );
  467.                 break;
  468.             case KILLBUF:
  469.                 (void) strcpy ( s_title, "Restore" );
  470.                 break;
  471.             case OPENFILES:
  472.                 (void) strcpy ( s_title, "Raise" );
  473.                 break;
  474.             default:
  475.                 break;
  476.         }
  477.         x = XTextWidth ( fs.font, s_title, strlen (s_title) );
  478.         XDrawString ( dpy, fs.ok, fs.gc,  (fs.button_width - x)/2,
  479.             fs.font -> ascent + 3, s_title, strlen (s_title) );
  480.         Display3D ( dpy, fs.ok, fs.ts, fs.bs, 1, 0 );
  481.     }
  482.     else if ( w == fs.cancel ) {
  483.         x = XTextWidth ( fs.font, "Cancel", 6 );
  484.         XDrawString ( dpy, fs.cancel, fs.gc, (fs.button_width - x)/2,
  485.             fs.font -> ascent + 3, "Cancel", 6 );
  486.         Display3D ( dpy, fs.cancel, fs.ts, fs.bs, 1, 0 );
  487.     }
  488.     else if ( w == fs.text -> window ) {
  489.         RefreshFileSelect ();
  490.     }
  491.     else if ( w == fs.scroll -> frame ) {
  492.         RefreshScrollFrame ( dpy,  fs.scroll );
  493.     }
  494.     else if ( w == fs.scroll -> scroll ) {
  495.         RefreshScrollBar ( dpy, fs.scroll );
  496.     }
  497.     while ( XCheckWindowEvent ( dpy, w, ExposureMask, &event ));
  498. }
  499.  
  500.  
  501. /*
  502. **    Function name : CleanButton
  503. **
  504. **    Description : Remet un boutton dans sa forme initiale.
  505. **    Input : La fenetre, le boutton.
  506. **    Ouput :
  507. */
  508. static void CleanButton ( w, button )
  509.     Window w;
  510.     unsigned int button;
  511. {
  512.     Display3D ( dpy, w, fs.ts, fs.bs, 1, 1 ); 
  513.     XGrabPointer ( dpy, w, True, ButtonReleaseMask, GrabModeAsync,
  514.         GrabModeAsync, w, None, CurrentTime );
  515.     WaitButtonRelease ( button );
  516.     Display3D ( dpy, w, fs.ts, fs.bs, 1, 0 );
  517. }
  518.  
  519.  
  520. /*
  521. **    Function name : RefreshFileSelect
  522. **
  523. **    Description : Postionne les elements
  524. **    Input : 
  525. **    Ouput :
  526. */
  527. static void RefreshFileSelect ()
  528. {
  529.     XClearWindow ( dpy, fs.text -> window );
  530.     Display3D ( dpy, fs.text -> window, fs.ts, fs.bs, 2, 1 ); 
  531.     ClipOn ( fs.text, NULL );
  532.     SetLinesTable ( fs.text );
  533.     RefreshPage ( fs.text );
  534.     ShowScrollFrame ( dpy, fs.text -> swin );    
  535.     ClipOff ( fs.text );
  536. }
  537.  
  538.  
  539. /*
  540. **    Function name : RefreshDirWindow
  541. **
  542. **    Description : Met a jour le texte dans le fenetre dir
  543. **    Input : Le nom, le type.
  544. **    Ouput :
  545. */
  546. static void RefreshDirWindow ( dir, type )
  547.     register char *dir;
  548.     register int type;
  549. {
  550.     register int start, width = 0;
  551.     register char *old = dir;
  552.  
  553.     XClearWindow ( dpy, fs.dir );
  554.        if ( type == KILLBUF || type == OPENFILES ) {
  555.               XDrawString ( dpy, fs.dir, fs.gc, MARGE, fs.font -> ascent + 5, dir, strlen(dir));
  556.               Display3D ( dpy, fs.dir, fs.ts, fs.bs, 1, 0 );    
  557.               return;
  558.         }
  559.     start = MARGE + XTextWidth ( fs.font, "Dir : ", 6 ) + 3;
  560.     width = fs.m_width - start -MARGE - XTextWidth ( fs.font, "...", 3 );
  561.     while ( XTextWidth ( fs.font, dir, strlen(dir)) > width ) 
  562.         dir ++;
  563.     XDrawString ( dpy, fs.dir, fs.gc, MARGE, fs.font -> ascent + 5, "Dir : ", 6 );
  564.     if ( old != dir ) {
  565.         XDrawString ( dpy, fs.dir, fs.gc, start, fs.font -> ascent + 5, "...", 3 );
  566.          XDrawString ( dpy, fs.dir, fs.gc,
  567.             start + XTextWidth ( fs.font, "...", 3 ), 
  568.             fs.font -> ascent + 5, dir, strlen(dir) );        
  569.     }
  570.     else
  571.          XDrawString ( dpy, fs.dir, fs.gc,
  572.             start, fs.font -> ascent + 5, dir, strlen(dir) );
  573.     Display3D ( dpy, fs.dir, fs.ts, fs.bs, 1, 0 );
  574. }
  575.  
  576.  
  577. /*
  578. **    Function name : SlectFileItem
  579. **
  580. **    Description : Selection d'un item.
  581. **    Input : La position, le type.
  582. **    Ouput :
  583. */
  584. static void SelectFileItem ( x, y, type )
  585. register int x, y;
  586. register int type;
  587. {
  588.     register int n;
  589.         register char *s, *end_name;
  590.         int len;
  591.         struct stat st;
  592.     char *tmp, *name_select;
  593.  
  594.     (void) MoveToXYinTextWindow (  fs.text,  x, y );
  595.     TextCursorOn ( fs.text );
  596.     TextCursorOff ( fs.text );
  597.  
  598.     if ( (n = fs.text -> no_current_line) >= fs.text -> lines_in_buf )
  599.         return;
  600.  
  601.     UpdateFileItem ( fs.select ); /* Eteint l'item courant */
  602.     UpdateFileItem ( n );     /* Allume l'item selectionne */
  603.     fs.select = n;
  604.     s = (char * ) GetCurrentLine ( fs.buf, &len );
  605.    
  606.        if ( type == KILLBUF || type == OPENFILES ) {
  607.               (void) sprintf ( fs.dirname, "Select : " );
  608.               (void) strncat ( fs.dirname, s, len );
  609.         len += strlen ( "Select : " );
  610.         fs.dirname [len] = '\0';
  611.               RefreshDirWindow ( fs.dirname, KILLBUF );
  612.               return;        
  613.      }
  614.     name_select = (char *) malloc ( (unsigned) len + 2 );
  615.     (void) strncpy ( name_select, s, len);
  616.     name_select [len] = '\0';
  617. #ifdef DEBUG
  618.     fprintf ( stderr, "\nfs.dirname = %s\nname_select = %s\n", fs.dirname, name_select );
  619. #endif DEBUG
  620.             len = strlen(fs.dirname) + strlen(name_select);
  621.     tmp = (char *) malloc ( (unsigned) len + 2 ); 
  622.     (void) sprintf ( tmp, "%s/%s", fs.dirname, name_select );
  623.         
  624.         if ( (strcmp ( tmp, "/.." ) == 0) || (strcmp ( name_select, ".") == 0) ) {
  625.            if ( tmp != 0 )
  626.                     (void) free (tmp);
  627.            if ( name_select != 0 )
  628.                     (void) free (name_select);
  629.                 return;
  630.     }
  631.     if ( stat ( tmp, &st ) == 0 ) {
  632.         if ( S_ISDIR(st.st_mode) != 0 ) {
  633.             if ( strcmp (name_select, "..") == 0 ) {
  634.                        end_name = (char * ) strrchr ( (char *) fs.dirname, '/' );
  635.                 len = strlen(fs.dirname) - strlen(end_name);
  636.                 tmp [len] = 0;
  637.                 if ( len == 0 ) {    /* Root */
  638.                     (void) strncpy ( tmp, "/", 1 );
  639.                     tmp [1] = 0;
  640.                 }
  641.             }
  642.             else {
  643.                 if ( strcmp (fs.dirname, "/") == 0 )
  644.                     (void) sprintf ( tmp, "%s%s", fs.dirname, name_select );
  645.                 else 
  646.                     (void) sprintf (tmp, "%s/%s", fs.dirname, name_select ); 
  647.             }
  648.             if ( ReadDir ( tmp ) == 0 ) {
  649.                 UpdateFileItem ( fs.select ); 
  650.                 fs.select = 0;
  651.                 RefreshDirWindow ( fs.dirname , FILESELECT );
  652.                 FirstPage ( fs.text );
  653.                 RefreshFileSelect ();
  654.             }
  655.             else
  656.                 RefreshDirWindow ( "Can't open dir", FILESELECT );
  657.         }
  658.         else
  659.             RefreshDirWindow ( fs.dirname, FILESELECT );    
  660.     }
  661.     else
  662.         RefreshDirWindow ( "Stat error", FILESELECT );
  663.     if ( name_select != 0 )
  664.         (void) free (name_select); 
  665.     if ( tmp != 0 )
  666.             (void) free (tmp);
  667. }
  668.  
  669.  
  670. /*
  671. **    Function name : UpdateFileItem
  672. **
  673. **    Description : Allume ou eteint l'item courant.
  674. **    Input : Le no de l'item. 
  675. **    Ouput :
  676. */
  677. static void UpdateFileItem ( n )
  678.     register int n;
  679. {
  680.     register int y;
  681.  
  682.     if ( (n == 0)
  683.         || ( n < (fs.text -> no_current_line - fs.text -> n1))
  684.         || ( n > (fs.text -> no_current_line + fs.text -> n2)))
  685.         return;
  686.  
  687.     y = n - ( fs.text -> no_current_line - fs.text -> n1 );
  688.     y *= fs.text -> font_height;
  689.     y += MARGE;
  690.  
  691.     XFillRectangle ( dpy, fs.text -> window,
  692.         fs.text -> Igc, MARGE,  y, 
  693.         fs.text -> width - ( 2 * MARGE ),
  694.         fs.text -> font_height + 1 );
  695. }
  696.  
  697.  
  698. /*
  699. **    Function name : UnmapFileSelect
  700. **
  701. **    Description : Cache le file selecteur.
  702. **    Input : 
  703. **    Ouput :
  704. */
  705. static void UnmapFileSelect ()
  706. {
  707.     XUnmapSubwindows ( dpy, fs.main );
  708.     XUnmapWindow ( dpy, fs.main );
  709.     XUnmapSubwindows ( dpy, fs.frame );
  710.     XUnmapWindow ( dpy, fs.frame );
  711.  
  712.     XReparentWindow ( dpy, fs.frame, DefaultRootWindow (dpy), 0, 0 );
  713. }
  714.  
  715.  
  716. /*
  717. **    Function name : ConfigFileSelect
  718. **
  719. **    Description : Prepare l'affichage, geometrie etc...
  720. **    Input : La fenetre parent. 
  721. **    Ouput :
  722. */
  723. static void ConfigFileSelect ( parent )
  724.     Window parent;
  725. {
  726.     XWindowAttributes att;
  727.     register int width, height, x, y, i;
  728.  
  729.     XGetWindowAttributes ( dpy, parent, &att );
  730.     width = (att.width / 4) * 3;
  731.     height =  (att.height / 4) * 3;
  732.     x = att.width / 8;
  733.     y = att.height / 8;
  734.  
  735.             fs.m_width = width - FS_SHADOW;
  736.         fs.m_height = height - (2*fs.title_height) - FS_SHADOW;
  737.  
  738.         XReparentWindow ( dpy, fs.frame, parent, x, y );
  739.     XResizeWindow ( dpy, fs.frame, width, height );
  740.     XResizeWindow ( dpy, fs.shadow, width - FS_SHADOW , height - FS_SHADOW );
  741.     XResizeWindow ( dpy, fs.main, 
  742.         width - FS_SHADOW, height - (2*fs.title_height) - FS_SHADOW );
  743.     XResizeWindow ( dpy, fs.title,  width -FS_SHADOW , fs.title_height );
  744.         XResizeWindow ( dpy, fs.dir,  width -FS_SHADOW , fs.title_height );
  745.     XMoveWindow ( dpy, fs.ok, ( width/3 ) - ( fs.button_width/2 ), 
  746.                 fs.m_height - fs.title_height - FS_SPACE );
  747.     XMoveWindow ( dpy, fs.cancel, ( width*2 / 3 ) - ( fs.button_width/2 ), 
  748.                 fs.m_height - fs.title_height - FS_SPACE );
  749.     XMapSubwindows (dpy, fs.main );
  750.     XMapWindow ( dpy, fs.main );
  751.     XMapSubwindows ( dpy, fs.frame);
  752.     XMapRaised ( dpy, fs.frame);
  753.  
  754.     x = fs.m_height - (3 * FS_SPACE) -  fs.button_height; 
  755.     x -= ( 2 * MARGE );
  756.     i = x / fs.text -> font_height;
  757.     x = fs.m_height - (3 * FS_SPACE) -  fs.title_height;
  758.  
  759.     SetScrollLinePage (  fs.scroll, i ); 
  760.             ShowWindowText ( dpy, fs.text, 
  761.                 fs.m_width - GetScrollWidth () - 1 - ( 2 * FS_SPACE) , x );
  762.     i = fs.text -> no_current_line - fs.text -> n1 - 1;
  763.     RefreshScroll ( dpy,  fs.scroll,  fs.m_width - FS_SPACE, x, i );
  764. }
  765.